home *** CD-ROM | disk | FTP | other *** search
- /* UNIX like write program. Kees Lemmens; Juli 1992
-
- This programs can be used to communicate between two login sessions
- on a multitasking ATARI ST (MINT).
- It behaves just like the UNIX write utility.
-
- Bugs/remarks:
- - I don't know how to determine the ttyname, so at this moment I use a
- variable TTYNAME defined by GETTY. If not found then ttyname will be
- "console". LOGNAME will be "root" if this variable is not found.
- - Some programs - like tcsh - send a signal TTOU when a foreign process
- attempts to write to their tty. This causes the foreign process to be
- suspended. To avoid this problem the write program has to ignore such
- signals.
- - Because I don't want to rely upon a UTMP file, you can also write to
- devices instead of users by using the -l option.
-
- Any questions or suggestions about this program can be send to:
- lemmens@dv.twi.tudelft.nl
- */
-
- #include <stdio.h>
- #include <fcntl.h> /* O_WRONLY etc. */
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include "ux_misc.h"
- #include <utmp.h>
- #include <signal.h>
-
- void set_bell(void)
- { long stack=0;
- char *conterm=(void *)0x484; /* CON attribs (bell, keyclick) */
-
- if(Super((void *)1L)==0)
- stack=Super((void *)0L); /* supervisor mode */
- *conterm |= 4; /* set bell attribute */
- if(stack) Super((void *)stack); /* back to user mode */
- }
-
- void fatal(char *txt)
- { fprintf(stderr,"WRITE: %s\n",txt);
- exit(1);
- }
-
- void do_write(char *totty)
- { int ttyfp;
- time_t sec;
- char c,warning[250],fulltty[100];
- char *name,*mytty,*endmsg="\r\n<EOT>\r\n";
-
- set_bell();
- time(&sec);
-
- if((name = getenv("LOGNAME")) == NULL) name = "root";
- if((mytty = getenv("TTYNAME")) == NULL) mytty = "console";
-
- mk_devnm(fulltty,totty);
- if((ttyfp=open(fulltty,O_WRONLY)) < 0)
- fatal("Can't open tty");
-
- sprintf(warning,"\7\r\n\tMessage from %s (%s) [ %.19s ] ...\r\n\7",
- name,mytty,ctime(&sec));
- write(ttyfp,warning,strlen(warning));
- puts("\7Write your message (Ctrl-D to stop)\7");
-
- while(read(1,&c,1),c != '\4' && c != '\32')
- { write(ttyfp,&c,1);
- if(c=='\r')
- { write(ttyfp,"\n",1);
- putchar('\n');
- }
- }
- write(ttyfp,endmsg,strlen(endmsg));
- close(ttyfp);
- }
-
- void usage(void)
- { puts("\nUsage: write [-l <line>] | [<user>]");
- exit(1);
- }
-
- void name2tty(char *name,char *totty)
- { extern int utmp_fd;
- int fl=0;
- struct utmp *w;
-
- setutent();
-
- while((w=getutent()) != NULL && !fl)
- { if(!strncmp(w->ut_name,name,sizeof(w->ut_name)) &&
- w->ut_type == USER_PROCESS)
- { if(Pkill(w->ut_pid,SIGNULL) == 0) /* process exists ? */
- { strncpy(totty,w->ut_line,sizeof(w->ut_line));
- fl=1;
- }
- else
- { w->ut_type=DEAD_PROCESS;
- setutent(); /* rewind and */
- pututline(w); /* correct UTMP entry */
- }
- }
- }
- endutent();
- if(!fl)
- { puts("User is not logged on");
- exit(0);
- }
- }
-
- void main(int argc,char *argv[])
- { char totty[100];
- int lfl=0;
-
- #ifdef MINT /* ignore signal [Attempted write to foreign tty] */
- signal(SIGTTOU,SIG_IGN);
- #endif
-
- if(argc<2) usage();
-
- while(--argc>0) /* parse options */
- { if(*argv[1]=='-')
- { switch(*(++argv[1]))
- { case 'l': lfl=1; break;
- default : usage();
- }
- ++argv;
- }
- }
- if(lfl) strcpy(totty,argv[1]);
- else name2tty(argv[1],totty);
-
- do_write(totty);
- }